#ifndef _TASK_H
#define _TASK_H
#include <stddef.h>

#define NO_SET_AFFINITY -1
#define FOLLOW_AFFINITY -2
#define INIT_AFFINITY   0   //-3


#ifdef SEG_BUFF
#define SEG_MASTER 1
#endif

//for task type
typedef int task_type; 
#define NOT_SET 0
#define STENCIL_TASK    1
#define NOAFFINITY_TASK 2
#define BLOCKING_TASK 3  
#define COMPOSITE_TASK 4
#define COMPOSITE_END_TASK 5
#define BARRIER_TASK 6

//
#define ADDR_CHUNKINIT 54
#define ADDR_CHUNKMORE 5

#ifdef SUPPORT_PARTITION
#define NO_SET_PART_ID -1
#endif

#ifdef ACEMESH_PARA
//__threal_local_fix long cur_time; 
#define  BUF_SIZE 2048
#define MAXT 10000000
#endif
//

//TODO
enum task_state
{
    ALLOCATED=0,
    READY,
    RUNNING
//    FREED
};
struct task
{
    int ref_count_t;
    int affinity_id;
#if defined(USE_PRIORITY_QUEUE) || defined(LOCAL_MULTI_PRIORI)
    int priority_id;
#endif
#ifdef REUSE_GRAPH
    int backup_ref;
    int reused;
    int stored;
    int is_base_task;
#endif
#ifdef TEMP_AFFI
    int bak_affinity_id;
#endif
    struct task* next;
#ifdef CONCURRENT_CONSTRUCT_GRAPH
    /*
    volatile int finished_lock;
    volatile int successor_lock;
    volatile int ref_lock;
    int edge;
    int state; //Four states: 0: initialization; 1：ready； 2：finish； 3：over
    int pre;
    */
   // int ref_lock __attribute__((aligned(32)));
    int successor_lock __attribute__((aligned(32)));
    int over __attribute__((aligned(32))); //0: False, 1: True
#endif
    //int spawn_order_id;
    //unsigned char extra_state;
};

#ifdef MTEST_LIGHT
struct mtest_task
{
    int *comm_handle1;
    int *comm_handle2;
    int comm_kind1;
    int comm_kind2;
    struct task* comm_task;

    struct mtest_task* next;
};
#endif
//struct task  task_constructor();
void task_constructor(struct task* self);
struct task  task_constructor_id(int id);

void slave_spawn(struct task* t);
void enqueue(struct task* t);

void adjust_affinity_id(struct task* self,struct task* another_task);
int slave_ref_count(struct task* self) ;

//for dag reuse
#ifdef REUSE_GRAPH
void store_ref_count(struct task* self);
void restore_ref_count(struct task* self);

void set_stored(struct task* self, int flag);
int get_stored(struct task* self);

void set_reused_flag(struct task* self, int flag);
int get_reused_flag(struct task* self);
#endif


#if defined(USE_PRIORITY_QUEUE) || defined(LOCAL_MULTI_PRIORI)
int get_priority_id(struct task* self) ; 
void set_priority_id(struct task* self,int id);
#endif
/*int get_spawn_order_id(struct task* self) ;
void set_spawn_order_id(struct task* self,int id);
*/
int slave_is_stolen_task(struct task* self);

struct empty_task
{
    struct task task_base;
};


#endif
